<template>
  <div
    class="tree-content"
    :class="{
      'top-dotted-line': childNodeIndex && Number(childNodeIndex) !== 0,
    }"
  >
    <div class="author-info">
      <img
        :src="
          node.authorPhotoUrl
            ? '/dev-api/attachment/down/' + node.authorPhotoUrl
            : defaultAvatar
        "
        class="avatar"
      />
      <span class="ml20">{{ node.createUserName }}</span>
    </div>
    <div class="reply-content-box">
      <div v-html="buildReplyDescribe(node)" class="mtb20"></div>
      <div class="footer row-flex mb5">
        <span>{{ node.createTime }}</span>
        <div class="reply-btn" @click="onReply(node)">
          <i class="fa fa-comment mr5"></i>
          回复
        </div>
        <div
          v-if="node.createUserId === userId && !node.hasChildren"
          class="delete-btn"
          @click="deleteReply(node.replyId)"
        >
          <i class="el-icon-delete-solid"></i>
          删除
        </div>
      </div>
      <div class="reply-content" v-if="node.isShowReply">
        <el-form
          ref="problemReplyFormRef"
          :model="problemReplyModel"
          :rules="problemReplyModelRules"
        >
          <el-form-item prop="replyDescribe">
            <el-input
              type="textarea"
              :rows="3"
              placeholder="评论一下"
              v-model="problemReplyModel.replyDescribe"
            ></el-input>
          </el-form-item>
          <div class="flex-row-end">
            <el-button type="success" size="mini" @click="onComment"
              >评论</el-button
            >
            <el-button size="mini" @click="onCancelReply(node)">取消</el-button>
          </div>
        </el-form>
      </div>
    </div>
    <div v-if="(node.children || {}).recordsTotal > 0" class="children-box">
      <tree-item
        v-for="(item, index) in (node.children || {}).data || []"
        :key="item.replyId"
        :node="item"
        :problemId="problemId"
        :childNodeIndex="index"
        :rootReplyId="rootReplyId"
        :currentPageInfo="node.children"
        :rootNodeIndex="rootNodeIndex"
      ></tree-item>
      <vxe-pager
        style="background: #f7f7f6"
        :current-page="(node.children || {}).startIndex"
        :page-size="(node.children || {}).pageSize"
        :total="(node.children || {}).recordsTotal"
        @page-change="onPageChange($event, node)"
        :pageSizes="[5, 10, 20, 50, 100]"
        :auto-hidden="true"
        :layouts="[
          'PrevJump',
          'PrevPage',
          'JumpNumber',
          'NextPage',
          'NextJump',
          'Total',
        ]"
      >
      </vxe-pager>
    </div>
  </div>
</template>

<script>
import request from "@/utils/request";
import { mapGetters } from "vuex";
const DELETE_OPERATION_TYPE = "delete";
const REPLY_OPERATION_TYPE = "reply";

export default {
  name: "TreeItem",
  inject: ["pageVue"],
  props: {
    node: {
      type: Object,
      default: function () {
        return {};
      },
    },
    problemId: {
      type: String,
      required: true,
    },
    rootReplyId: {
      type: String,
      required: true,
    },
    childNodeIndex: {
      type: Number,
    },
    rootNodeIndex: {
      type: Number,
    },
    isRootNode: {
      type: Boolean,
      default: false,
    },
    currentPageInfo: {
      type: Object,
      default: function () {
        return {
          data: [],
          pageSize: 10,
          recordsFiltered: 0,
          recordsTotal: 0,
          startIndex: 0,
          draw: 1,
        };
      },
    },
  },
  computed: {
    ...mapGetters(["userId"]),
  },
  data() {
    return {
      defaultAvatar: require("@/assets/images/profile.png"),
      problemReplyModel: {
        problemId: undefined,
        rootReplyId: undefined,
        parentReplyId: undefined,
        replyDescribe: undefined,
      },
      problemReplyModelRules: {
        replyDescribe: [
          {
            required: true,
            message: "评论不能为空",
            trigger: "change",
          },
        ],
      },
      localCurrentPageInfo: this.currentPageInfo,
    };
  },
  methods: {
    onReply(node) {
      this.problemReplyModel.problemId = this.problemId;
      this.problemReplyModel.rootReplyId = this.rootReplyId;
      this.problemReplyModel.parentReplyId = node.replyId;
      this.$set(node, "isShowReply", true);
    },
    onCancelReply(node) {
      this.$set(node, "isShowReply", false);
      this.resetReplyModelInfo();
    },
    resetReplyModelInfo() {
      this.problemReplyModel = {
        problemId: undefined,
        rootReplyId: undefined,
        parentReplyId: undefined,
        replyDescribe: undefined,
      };
    },
    onComment() {
      this.$refs["problemReplyFormRef"].validate((valid) => {
        if (valid) {
          const appLoading = this.appLoading("数据提交中...");
          request({
            url: "/eip/marketAppReply/save",
            method: "post",
            data: {
              model: this.problemReplyModel,
            },
          })
            .then((res) => {
              const { success, message } = res;
              if (success) {
                this.msgSuccess("回复成功！");
                this.refreshReplyHandle(REPLY_OPERATION_TYPE);
              } else {
                this.msgError(message || "回复失败！");
              }
            })
            .finally(() => {
              appLoading.close();
            });
        }
      });
    },
    deleteReply(replyId) {
      this.$confirm("确定要删除此列吗？", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          request({
            url: "/eip/marketAppReply/delete",
            method: "post",
            data: {
              delete: JSON.stringify([{ replyId: replyId }]),
            },
          }).then((r) => {
            const { success, message } = r;
            if (success) {
              this.msgSuccess("删除成功！");
              this.refreshReplyHandle(DELETE_OPERATION_TYPE);
            } else {
              this.msgError(message || "删除失败,先删除子节点再删除！");
            }
          });
        })
        .catch(() => {});
    },
    refreshReplyHandle(operationType) {
      if (this.localCurrentPageInfo.startIndex === 0) {
        this.localCurrentPageInfo.startIndex = 1;
      }
      if (this.isRootNode && this.pageVue) {
        if (operationType === DELETE_OPERATION_TYPE) {
          this.pageVue.fetchData(
            this.buildReplyRefreshPageInfoParams(
              operationType,
              this.pageVue.query
            ),
            "list",
            false
          );
          this.resetReplyModelInfo();
        } else {
          if (this.pageVue.query.data[this.rootNodeIndex].isShowReply) {
            this.$set(
              this.pageVue.query.data[this.rootNodeIndex],
              "isShowReply",
              false
            );
          }
          if (!this.pageVue.query.data[this.rootNodeIndex].hasChildren) {
            this.$set(
              this.pageVue.query.data[this.rootNodeIndex],
              "hasChildren",
              true
            );
          }
          this.loadChildrenReply(
            _.extend(
              {},
              this.buildReplyRefreshPageInfoParams(
                operationType,
                this.localCurrentPageInfo
              ),
              {
                draw: 1,
                query: {
                  rootReplyId: this.rootReplyId,
                  problemId: this.problemId,
                },
              }
            ),
            this.pageVue.query.data[this.rootNodeIndex]
          );
        }
      } else {
        if (
          operationType === DELETE_OPERATION_TYPE &&
          this.localCurrentPageInfo.recordsTotal <= 1
        ) {
          // 删除时，子节点只剩一条，需要刷新当前页第一层节点数据，以此更新删除按钮状态
          this.pageVue.fetchData(
            this.buildReplyRefreshPageInfoParams(
              operationType,
              this.pageVue.query,
              false
            ),
            "list",
            false
          );
        } else {
          this.loadChildrenReply(
            _.extend(
              {},
              this.buildReplyRefreshPageInfoParams(
                operationType,
                this.localCurrentPageInfo
              ),
              {
                draw: 1,
                query: {
                  rootReplyId: this.rootReplyId,
                  problemId: this.problemId,
                },
              }
            ),
            this.pageVue.query.data[this.rootNodeIndex]
          );
        }
      }
    },
    buildReplyRefreshPageInfoParams(
      operationType,
      pageInfo,
      hasCalculateRemoveThreshold = true
    ) {
      const { recordsTotal, startIndex, pageSize } = pageInfo;
      let params = {
        start: (startIndex - 1) * pageSize,
        length: pageSize,
      };
      if (
        operationType === DELETE_OPERATION_TYPE &&
        hasCalculateRemoveThreshold
      ) {
        const condition =
          recordsTotal - 1 <= (startIndex - 1) * pageSize && recordsTotal != 0;
        if (condition) {
          params = {
            start: (startIndex - 2) * pageSize,
            length: pageSize,
          };
        }
        this.localCurrentPageInfo = _.extend(this.localCurrentPageInfo, {
          startIndex: startIndex - 1,
        });
      }
      return params;
    },
    onPageChange({ currentPage, pageSize }, currentNode) {
      this.loadChildrenReply(
        {
          start: (currentPage - 1) * pageSize,
          length: pageSize,
          draw: 1,
          query: {
            rootReplyId: this.rootReplyId,
            problemId: this.problemId,
          },
        },
        currentNode
      );
      this.localCurrentPageInfo = _.extend(this.localCurrentPageInfo, {
        startIndex: currentPage,
      });
    },
    loadChildrenReply(params, currentNode) {
      const appLoading = this.appLoading("数据加载中...");
      request({
        url: "/eip/marketAppReply/selectSubReplyPage",
        method: "post",
        data: params,
      })
        .then((res) => {
          currentNode.children = res;
          this.localCurrentPageInfo = res;
          this.resetReplyModelInfo();
        })
        .catch((err) => {
          console.error("loadChildrenReply：", err);
          this.msgError("数据加载失败！");
        })
        .finally(() => {
          appLoading.close();
        });
    },
    buildReplyDescribe(reply) {
      const { replyDescribe, targetUserName } = reply;
      if (targetUserName) {
        return `回复 ${targetUserName}：${replyDescribe}`;
      }
      return replyDescribe;
    },
  },
};
</script>

<style lang="scss" scoped>
img {
  border-radius: 5px;
}
.tree-content {
  padding: 10px;
  .author-info {
    display: flex;
    flex-flow: row nowrap;
    align-items: center;
  }
  .reply-content-box {
    padding: 10px 30px;
    color: #999;
    .footer {
      color: #999;
    }

    .reply-content {
      background: #f7f7f7;
      padding: 15px;
    }
  }
}

.ml20 {
  margin-left: 20px;
}
.reply-btn {
  color: #999;
  cursor: pointer;
  font-size: 12px;
  flex: 1;
  display: flex;
  align-items: flex-end;
  justify-content: flex-end;
}
.reply-btn:hover {
  color: #22ac38;
}
.delete-btn:hover {
  color: #22ac38;
}
.delete-btn {
  margin-left: 10px;
  margin-top: 2px;
  font-size: 12px;
  cursor: pointer;
}
.row-flex {
  display: flex;
  flex-flow: row nowrap;
}
.flex-row-end {
  display: flex;
  flex-flow: row nowrap;
  justify-content: flex-end;
}
.mtb20 {
  margin: 20px 0px;
}
.avatar {
  width: 60px;
  height: 60px;
}

.top-dotted-line {
  border-top: 2px dotted #e2e2e2;
}
.children-box {
  background: #f7f7f6;
  padding: 10px 20px;
}
</style>
